﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Crank.Core
{
    public class DataModel
    {
        public IDictionary<string, EntityDef> Entities { get; protected set; }
        public IList<LinkDef> Links { get; protected set; }

        public EntityDef GetEntityByName(string name)
        {
            if (!Entities.ContainsKey(name))
                Entities.Add(name, new EntityDef(name));
            return Entities[name];
        }

        public DataModel()
        {
            Entities = new Dictionary<string, EntityDef>();
            Links = new List<LinkDef>();
        }
    }

    public class AttributeDef
    {
        public string Name { get; set; }
        public bool IsRequired { get; set; }
        public string Type { get; set; }
        public bool IsKey { get; set; }
        public bool IsAuto { get; set; }

        public AttributeDef(string name)
        {
            Name = name;
            IsRequired = true;
        }

        public AttributeDef(AttributeDef toCopy) : this( toCopy.Name )
        {
            IsRequired = toCopy.IsRequired;
            Type = toCopy.Type;
            IsKey = toCopy.IsKey;
            IsAuto = toCopy.IsAuto;
        }

        public AttributeDef() : this("_") { }
    }

    public class EntityDef
    {
        public IList<AttributeDef> Attributes { get; protected set; }
        public string Name { get; protected set; }
        public EntityDef(string name)
        {
            Name = name;
            Attributes = new List<AttributeDef>();
        }

        public IEnumerable<AttributeDef> Keys
        {
            get
            {
                return Attributes.Where(a => a.IsKey);
            }
        }
    }

    public class LinkDef
    {
        public string Type { get; set; }
        public AttributeDef Detail { get; set; }
        public EntityDef LHS { get; set; }
        public EntityDef RHS { get; set; }

        public IList<string> SourceColumns { get; protected set; }

        public LinkDef(string type)
        {
            Type = type;
            SourceColumns = new List<string>();
        }

        public LinkDef(LinkDef toCopy) : this( toCopy.Type)
        {
            LHS = toCopy.LHS;
            RHS = toCopy.RHS;
            Detail = new AttributeDef(toCopy.Detail);
        }
    }
}
